<template>
  <div id="qcMaterialTimeDiv">
    <Breadcrumb content="结果录入(按时间)" />
    <div class="bodyContent">
      <Splitpanes>
        <Pane size="30">
          <!-- 质控靶值设定  -->
          <div class="saveBtn">
            <vxe-checkbox v-model="searchForm.isShowAll" size="small" content="显示过期的质控品" checked-value="1" unchecked-value="0" @change="findMaterialItemTree"></vxe-checkbox>
          </div>
          <vxe-toolbar perfect>
            <template #buttons>
              <div class="smallToolTitle">仪器</div>
              <vxe-select v-model="searchForm.instrIds" multiple :filterable="true" clearable @change="valueChangeEvent">
                <vxe-option v-for="instr in instrList" :key="instr.id" :value="instr.id" :label="instr.instrName"></vxe-option>
              </vxe-select>
              <vxe-button type="text" class="button-blue" icon="vxe-icon-refresh" content="刷新" :loading="treeloading" @click="findMaterialItemTree"></vxe-button>
            </template>
          </vxe-toolbar>
          <el-scrollbar style="height: calc(100% - 40px)">
            <div class="sampleType">
              <el-scrollbar>
                <el-tree :expand-on-click-node="false" :default-expanded-keys="expandedkeys" :data="materialItemTree" :props="defaultProps" node-key="id" ref="dataTreeRef" highlight-current class="tools-tree" @node-click="handleClickType" v-loading="treeloading">
                  <template #default="{ data, node }">
                    <div style="float: right">
                      <img :src="`${getAssetsFile('images/qc/' + data.type + '.png')}`" style="width: 15px; height: 15px; margin-right: 10px" />
                      {{ data.name }}
                    </div>
                  </template>
                </el-tree>
              </el-scrollbar>
            </div>
          </el-scrollbar>
        </Pane>
        <Pane size="70">
          <vxe-toolbar perfect>
            <template #buttons>
              质控日期：
              <vxe-input v-model="form.qcDate" placeholder="选择日期" type="date" valueFormat="yyyy-MM-dd" @change="getIQCByIns()"></vxe-input>

              <vxe-button type="text" icon="vxe-icon-save" class="button-blue" content="保存" @click="saveIQCResult"></vxe-button>
            </template>
          </vxe-toolbar>
          <div class="tableBox">
            <vxe-table ref="resultByDateTable" :loading="rloading" border resizable show-overflow :data="ansWithResults" :edit-config="{
                trigger: 'click',
                mode: 'cell'
              }" height="100%" class="result-table" :menu-config="tableMenu" @menu-click="contextMenuClickEvent" @cell-click="cellClickEvent" :mouse-config="{ selected: true }" :keyboard-config="{
                isArrow: true,
                isTab: true,
                isEdit: true
              }">
              <vxe-column title="项目名称" min-width="160">
                <template #default="{ row }">
                  {{ row.ans.itemDictCode + ' ' + row.ans.itemDictName }}
                </template>
              </vxe-column>
              <vxe-column :title="'次数' + i" :field="'result' + i" min-width="100" v-for="i in itemNum" :key="i" header-align="center" :edit-render="{
                  autofocus: '.vxe-input--inner',
                  autoselect: true
                }" class-name="number-right">
                <template #default="{ row }">
                  <div :class="[
                      row.ansSequenceResults[i - 1].z >= 3
                        ? 'zS3'
                        : row.ansSequenceResults[i - 1].z >= 2
                        ? 'zS2'
                        : '',
                      row.ansSequenceResults[i - 1].z <= -3
                        ? 'zS-3'
                        : row.ansSequenceResults[i - 1].z <= -2
                        ? 'zS-2'
                        : ''
                    ]">
                    <i :class="
                        row.ansSequenceResults[i - 1].isOutControl
                          ? 'el-icon-warning'
                          : row.ansSequenceResults[i - 1].isAlarm
                          ? 'el-icon-warning-outline'
                          : row.ansSequenceResults[i - 1].isBestInDay
                          ? 'el-icon-success'
                          : ''
                      "></i>
                    <span>{{ row.ansSequenceResults[i - 1].result }}<div> {{getResultCv(row.ansSequenceResults[i - 1])}}</div></span>
                  </div>
                </template>
                <template #edit="{ row, $rowIndex, column }">
                  <vxe-input :ref="'resultInput' + $rowIndex" v-model="row.ansSequenceResults[i - 1].result" @input="originalResultChange(row, i)" @keydown.native.enter="resultEnterEvent(row, rowIndex, i, column)"></vxe-input>
                </template>
              </vxe-column>

              <vxe-column field="mean" title="靶值" min-width="100" header-align="center" class-name="number-right">
                <template #default="{ row }">
                  {{ row.ansSequenceResults[0] ? row.ansSequenceResults[0].mean : '' }}
                </template>
              </vxe-column>
              <vxe-column field="sd" title="SD" min-width="100" header-align="center" class-name="number-right">
                <template #default="{ row }">
                  {{ row.ansSequenceResults[0] ? row.ansSequenceResults[0].sd : '' }}
                </template>
              </vxe-column>
              <vxe-column field="cv" title="CV" min-width="100" header-align="center" class-name="number-right">
                <template #default="{ row }">
                  {{ row.ansSequenceResults[0] ? row.ansSequenceResults[0].cv : '' }}
                </template>
              </vxe-column>
              <vxe-column title="确认人" width="100" header-align="center"> </vxe-column>
            </vxe-table>
          </div>
        </Pane>
      </Splitpanes>
    </div>
    <!-- 失控记录抽屉 -->
    <el-drawer v-model="showDrawer" show-close title="失控记录" :with-header="false" modal-class="drawerBulkModal" direction="rtl" :size="'calc(100vw - ' + 70 + 'px)'" :modal="false" append-to-body>
      <!-- :style="[
        { width: 'calc(100% - ' + 70 + 'px)' },
        { left: 70 + 'px' },
        { height: 'calc(100vh - 50px)' },
        { top: '50px' }
      ]" -->
      <GoBack :content="materialItemTree.id ? '编辑' : '新建'" :backUrl="'/qcmaterialtime'" @click.native="clearDrawer" />
      <div class="iqcOutControl">
        <QcOutControlRecChart ref="qcOutControlRecChartRef" />
      </div>
    </el-drawer>
  </div>
</template>
<script setup lang="ts">
// 引入组件区 ==========
import { ref, reactive, getCurrentInstance, onMounted } from 'vue';
import Breadcrumb from '@/components/Breadcrumb.vue';
import { Splitpanes, Pane } from 'splitpanes';
import { formatDateTime, getAssetsFile } from '@/utils/common';
import { VxeMessage, VxeNotifyType } from '@/utils/CommonMessage'; //提示框
import { isEmpty } from 'lodash';
import QcOutControlRecChart from './QcOutControlRecChart.vue'; //失控记录图表
import GoBack from '@/components/GoBack.vue'; //返回组件
import { log } from 'console';

// 全局变量定义区 ==========
let { proxy }: any = getCurrentInstance();
// 加载状态
let showDrawer = ref(false);
let treeloading = ref(false); //质控靶值树上的刷新
let rloading = ref(false);
let materialItemTree: any = reactive([]); //最左侧质控靶值设定树数据
let disabledTag = ref(true);
let currentCellIQCResult: any = reactive({});
let qcResultId = ref(null);
let qcOutControlRecChartRef: any = ref(null);
let instrList: any = reactive([]); //左侧仪器下拉项
let expandedkeys: any = reactive([]);

// 最左侧的树
let defaultProps = {
  children: 'children',
  label: 'name'
};
let sltMaterItem: any = reactive({}); //最左侧树选中行
let searchForm = ref({
  searchValue: '',
  instrId: '',
  instrIds: [],
  isShowAll: '0'
});

const itemNum = ref(4);
let ansWithResults: any = reactive([]);
let form = reactive({
  qcDate: formatDateTime(new Date(), 'yyyy-MM-dd')
});

let ans = reactive({
  instrId: '',
  materialId: '',
  qcItemId: '',
  itemDictId: ''
});

// 方法定义区 =============
// 页面加载时更新
onMounted(() => {
  findInstrSetupList();
  findMaterialItemTree(); // 获取最左侧质控靶值树数据
});
// 获取左侧仪器下拉选项数据(标题)
function findInstrSetupList() {
  instrList.length = 0; //放入数据前清空数据
  const url = '/lis/instrSetup/getInstrSetupList';
  proxy.$http
    //注意此处的数据条数
    .get(url, {
      params: { seachValue: '' }
    })
    .then((res: any) => {
      instrList.push(...res.data);
    })
    .catch((err: any) => {
      VxeMessage('获取左侧仪器表格数据异常', VxeNotifyType.error);
    });
}

// 仪器下拉选择 改变
function valueChangeEvent() {
  findMaterialItemTree();
}

// 获取最左侧质控靶值树 刷新
function findMaterialItemTree() {
  treeloading.value = true;
  materialItemTree.length = 0; //放入数据前清空数据
  expandedkeys.length = 0;

  const url = '/api/qc/qcMaterial/findMaterialTree';
  proxy.$http
    //注意此处的数据条数
    .get(url, { params: { isShowAll: searchForm.value.isShowAll, instrIds: searchForm.value.instrIds } })
    .then((res: any) => {
      if (!IsEmpty(res.data)) {
        materialItemTree.push(...res.data);

        getExpandedkeys();
        //materialTargetList.length = 0;
        sltMaterItem = reactive({});
        //如果点击的当前行数据是父级，那就禁用质控品维护的按钮
        if (!sltMaterItem.id) {
          disabledTag.value = true;
        } else {
          //如果点击的当前行数据是子集，那就不需要禁用质控品维护的按钮
          disabledTag.value = false;
        }
        handleClickType(res.data[0], null, null);
      }
      treeloading.value = false;
    })
    .catch((err: any) => {
      treeloading.value = false;
      VxeMessage('获取最左侧质控靶值树异常', VxeNotifyType.error);
    });
}

//点击左侧树
function handleClickType(obj: any, node: any, data: any) {
  const isSearch = obj.isSearch;
  if (isSearch == '0') {
    sltMaterItem = obj;
    ans.materialId = obj.id;
    findQcResultList();
  } else {
    ansWithResults.length = 0;
    sltMaterItem = reactive({});
  }
}

// ------------------------------------------------------------
//**判断为空*/
function IsEmpty(value: any) {
  if (value === undefined || value === '' || value === null) {
    return true;
  }
  if (JSON.stringify(value) === '{}') {
    return true;
  }
  return false;
}

// 获取结果数据
function findQcResultList() {
  rloading.value = true;
  ansWithResults.length = 0;
  const url = '/api/qc/qcMaterialItemResult/getQcMaterialItemResultData';
  proxy.$http
    //注意此处的数据条数
    .get(url, {
      params: { materialId: ans.materialId, qcDate: form.qcDate }
    })
    .then((res: any) => {
      if (res.data && res.data.length > 0) {
        setIQCMaterialDate(res);
      } else {
        rloading.value = false;
      }
    })
    .catch((err: any) => {
      rloading.value = false;
      VxeMessage('获取右侧获取质控项目表格数据异常', VxeNotifyType.error);
    });
}

function saveIQCResult() {
  const data = {
    qcDate: form.qcDate,
    ansWithResults: []
  };
  ansWithResults.forEach((item, index) => {
    data.ansWithResults[index] = {
      materialItemId: item.ans.id,
      itemDefine: item.ans.itemDefine,
      iqcSequenceResults: []
    };
    item.ansSequenceResults.forEach((value) => {
      let resultObj = value;
      if (isEmpty(resultObj.id) && !isEmpty(resultObj.result)) {
        resultObj.materialId = item.ans.materialId;
        resultObj.materialItemId = item.ans.materialItemId;
        resultObj.qcItemId = item.ans.qcItemId;
        resultObj.instrId = item.ans.instrId;
        resultObj.itemDictId = item.ans.itemDictId;
        resultObj.batchNum = item.qcMaterial.batchNum;
        resultObj.horizontal = item.qcMaterial.horizontal;
        resultObj.qcNo = item.qcMaterial.qcNo;
        resultObj.qcDate = form.qcDate + ' 00:00:00';
      }
      data.ansWithResults[index].iqcSequenceResults.push(resultObj);
    });
  });
  const url = '/api/qc/qcMaterialItemResult/addQcMaterialItemResult';
  proxy.$http
    //注意此处的数据条数
    .post(url, data)
    .then((res: any) => {
      findQcResultList();
      if (res.status.code !== 1) {
        VxeMessage(res.status.msg, VxeNotifyType.error);
      } else {
        VxeMessage(res.status.msg, VxeNotifyType.success);
      }
    })
    .catch((err: any) => {
      VxeMessage(err, VxeNotifyType.error);
    });
}

const tableMenu = {
  body: {
    options: [
      [
        {
          code: 'IQCOutControl',
          name: '失控处理',
          prefixIcon: 'el-icon-warning-outline',
          disabled: false
        }
      ]
    ]
  },
  visibleMethod: ({ options, row, columnIndex }) => {
    options.forEach((list) => {
      list.forEach((item) => {
        // 当结果中的isOutControl 为false时，禁用右键菜单中的 失控处理 IQCOutControl
        if (item.code === 'IQCOutControl') {
          currentCellIQCResult = row.ansSequenceResults[columnIndex - 1];
          item.disabled = !row.ansSequenceResults[columnIndex - 1].isOutControl;
        }
      });
    });
    // 当结果中的isOutControl 为true时，显示右键菜单
    // return row.sequenceResults[columnIndex - 1].isOutControl;
    return true;
  }
};

function contextMenuClickEvent({ menu, row, columnIndex }) {
  proxy.$nextTick(() => {
    qcResultId.value = row.ansSequenceResults[columnIndex - 1].id;
  });
  //proxy[menu.code]();
  if (menu.code == 'IQCOutControl') {
    IQCOutControl();
  }
}

function cellClickEvent({ row, column, columnIndex }) {
  if (column.field === 'result' + columnIndex) {
    currentCellIQCResult = row.ansSequenceResults[columnIndex - 1];
    qcResultId.value = row.ansSequenceResults[columnIndex - 1].id;
  }
}
// 点击右键菜单里的失控处理
function IQCOutControl() {
  showDrawer.value = true;
  proxy.$nextTick(() => {
    qcOutControlRecChartRef.value.initPage(qcResultId);
  });
}
function clearDrawer() {
  showDrawer.value = false;
}
// 处理返回的数据
function setIQCMaterialDate(res: any) {
  ansWithResults.length = 0;
  res.data.forEach((item) => {
    const resultList = [];
    for (let i = 0; i < itemNum.value; i++) {
      resultList.push({
        qcSequence: i + 1, //当天质控次数
        result: '', //质控结果
        numResult: null, //质控数值结果
        mean: null, //均值/靶值
        sd: null, //标准差
        z: null, //Z分数值
        alarmRules: '', //警报规则
        isAlarm: false, //是否警报
        isBestInDay: false, //最优结果
        isOutControl: false, //是否失控
        outControlRules: '', //失控规则
        isOutControlHandled: false //是否失控处理
      });
    }
    item.ansSequenceResults.forEach((result) => {
      // 每天质控次数的数据类型
      resultList[Number(result.qcSequence) - 1] = result;
    });
    item.ansSequenceResults = resultList;
    ans = item.ans;
    rloading.value = false;
  });
  ansWithResults.push(...res.data);
}

function originalResultChange(row, i) {
  if (IsEmpty(row.ansSequenceResults[i - 1].result) || /^\d+(\.\d*)?$/.test(row.ansSequenceResults[i - 1].result.trim())) {
    return;
  }
  VxeMessage('请输入数字', VxeNotifyType.error);

  // this.$notify.error({
  //   title: '输入错误',
  //   message: '请输入数字',
  //   duration: 3000
  // });
}

function getIQCByIns() {
  ansWithResults.length = 0;
  findQcResultList();
}

function getExpandedkeys() {
  for (const materialItem of materialItemTree) {
    pusExpandedkeys(materialItem);
  }
}

function pusExpandedkeys(obj: any) {
  const children = obj.children;
  if (obj.type == 'instrClass') {
    //expandedkeys.push(obj.id);
  }
  if (!IsEmpty(children) && children.length > 0) {
    for (const ch of children) {
      pusExpandedkeys(ch);
    }
  }
}

function getResultCv(row: any) {
  if (!IsEmpty(row.id)) {
    if (!IsEmpty(row.mean) && !IsEmpty(row.result)) {
      let cv = ((Math.abs(row.mean - row.result) / row.mean) * 100).toFixed(2);
      return ' CV:' + cv;
    }
  }
}
</script>

<style lang="scss" scoped>
#qcMaterialTimeDiv {
  height: 100%;
  .bodyContent {
    height: calc(100% - 60px);
    .splitpanes {
      background-color: $base-white;
      // 显示过期的质控品按钮
      .saveBtn {
        float: right;
        margin: 10px 50px;
      }
      // 附加按钮间距
      .button-blue,
      .button-red {
        margin: 5px 0 5px 5px;
      }
      // 最右侧质控靶值设定表格
      .tableBox {
        height: calc(100% - 40px);
      }
    }

    :deep(.result-table) {
      .number-right .vxe-cell {
        text-align: right;
        span {
          display: inline-block;
          width: calc(100% - 12px);
          div {
            display: inline-block;
            background-color: #ebe9e9;
            width: calc(100% - 80px);
          }
        }
      }
      .el-icon-warning {
        color: red;
      }
      .el-icon-warning-outline {
        color: $warning-color;
      }
      .el-icon-success {
        color: $success-color;
      }
      .zS2 {
        color: $warning-color;
      }
      .zS3 {
        color: $danger-color;
      }
      .zS-2 {
        color: $brand-color;
      }
      .zS-3 {
        color: #6600ff;
      }
    }
  }
  :deep(.drawerBulkModal) {
    inset: 50px 0 0 70px !important;
  }
  :deep(.el-drawer__body) {
    .iqcOutControl {
      width: 800px;
      // margin: 0 auto;
      transform: translateX(65%);
    }
  }
}
</style>
